/*
 *  Copyright (C) 2010 JS.MinecraftSavior
 *
 *  This file is part of the Minecraft Savior utility.
 *
 *  Minecraft Savior is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Minecraft Savior is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.utility.MinecraftSavior.file;

import com.utility.MinecraftSavior.ui.MCS;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

public class Decompress {
    private static final int BUFFER_SIZE = 8192;

    public static void decompressDir(String srcDirStr, String dstDirStr) {
        try {
            // Get file versions of directory strings passed as parameters
            File srcZip = new File(srcDirStr);
            File dstDir = new File(dstDirStr);

            // Make destination directory or delete what's there to make new one
            if (!dstDir.isDirectory())
                dstDir.mkdir();
            else {
                deleteDirectory(dstDir.getAbsolutePath());
                dstDir.mkdir();
            }

            // Initialize zip file that will be read from
            ZipFile zFile = new ZipFile(srcZip);

            // Initialize dataBuffer and numBytesRead for IO
            int numBytesRead;
            byte[] dataBuffer = new byte[BUFFER_SIZE];

            // Process each entry in the zip file
            Enumeration e = zFile.entries();
            while (e.hasMoreElements()) {
                // Get current zip entry
                ZipEntry zEntry = (ZipEntry) e.nextElement();

                // Display output for user within the restoreStatusTextArea
                MCS.updateRestoreStatusTextArea("\tDecompressing: " + zEntry);

                // Get destination and parent directories
                File dstFile = new File(dstDir, zEntry.getName());
                File dstPar = dstFile.getParentFile();

                // Make parent directory structure when needed
                dstPar.mkdirs();

                if (!zEntry.isDirectory()) {
                    // Initialize readable input stream from current zip entry
                    BufferedInputStream bis = new BufferedInputStream
                            (zFile.getInputStream(zEntry));

                    // Initialize writable output stream at destination directory
                    BufferedOutputStream bos = new BufferedOutputStream
                            (new FileOutputStream(dstFile), BUFFER_SIZE);

                    // Write what is read from input stream to output stream
                    while ((numBytesRead = bis.read(dataBuffer, 0, BUFFER_SIZE)) != -1) {
                        bos.write(dataBuffer, 0, numBytesRead);
                    }

                    bis.close();

                    bos.flush();
                    bos.close();
                }
            }
        } catch (IOException ex) {
        }
    }

    // Recursively delete a directory's contents then the directory itself
    private static void deleteDirectory(String dirStr) {
        // Get file representation of dirStr
        File dirFile = new File(dirStr);

        if (dirFile.isDirectory()) {
            // Get all the files in directory
            File[] list = dirFile.listFiles();

            // Check to see that list is not empty
            if (list != null) {
                // Iterate over each file
                for (int i = 0; i < list.length; i++) {
                    File curFile = list[i];

                    // If file is directory, recursively delete it's contents
                    if (curFile.isDirectory())
                        deleteDirectory(curFile.getAbsolutePath());

                    // Delete file
                    curFile.delete();
                }
            }

            // Delete original directory since its contents have been cleared
            dirFile.delete();
        }
    }
}
